package multi_thread.master.tools;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

/**
 * @author Cheng Jun
 * Description: 发令枪 CountDownLatch，初始化一个count数字。
 * CountDownLatch中count down是倒数的意思，latch则是门闩的含义。整体含义可以理解为倒数的门栓，
 * 有一点“三二一，芝麻开门”的感觉。CountDownLatch 的作用也是如此
 * https://www.jianshu.com/p/128476015902
 *
 * CountDownLatch 和 CyclicBarrier 都是在某种条件满足下，同时执行 调用了其await方法 的线程。
 * CountDownLatch 是在倒数到 0 时，同时执行；CyclicBarrier 是在所有的参赛选手（所有线程）都到了栅栏时，同时继续往下执行；
 *
 * 判断线程池中的线程是否全部执行完毕的一种解决方案则是使用闭锁(CountDownLatch)来实现。
 * @version 1.0
 * @date 2020/3/6 17:02
 * @see CountDownLatch
 * @see CyclicBarrierExample
 */
public class CountDownLatchExample {

    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        // CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " 完成一半工作");
            try {
                // Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted.
                // countDownLatch.await();
                // cyclicBarrier.await();
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName() + " 完成");
                countDownLatch.countDown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " 完成另一半工作");
            try {
                Thread.sleep(1000);
                countDownLatch.countDown();
                // cyclicBarrier.await();
                System.out.println(Thread.currentThread().getName() + " 完成");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        // System.out.println(Thread.currentThread().getName() + " 我自己的工作已经完成，等待另外两个线程完成工作！");
        try {
            // countDownLatch.countDown();
            countDownLatch.await();
            // cyclicBarrier.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " 所有工作已经完成！");
    }
}
